home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / src / mountlist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  11.5 KB  |  457 lines

  1. /* mountlist.c -- return a list of mounted filesystems
  2.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21. #ifndef NO_INFOMOUNT
  22.  
  23. #include <stdio.h>
  24. #include <sys/types.h>
  25. #include "mountlist.h"
  26.  
  27. #ifdef STDC_HEADERS
  28. #include <stdlib.h>
  29. #else
  30. void free (void *ptr);
  31. #endif
  32. #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
  33. #include <string.h>
  34. #else
  35. #include <strings.h>
  36. #endif
  37.  
  38. char *strstr (const char *haystack, const char *needle);
  39. /* void error (void);  FIXME -- needed? */
  40.  
  41. #ifdef HAVE_SYS_PARAM_H
  42. #include <sys/param.h>
  43. #endif
  44.  
  45. #if defined (MOUNTED_GETFSSTAT)    /* __alpha running OSF_1 */
  46. #include <sys/mount.h>
  47. #include <sys/fs_types.h>
  48. #endif                /* MOUNTED_GETFSSTAT */
  49.  
  50. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  51. #include <mntent.h>
  52. #if !defined(MOUNTED)
  53. #if defined(MNT_MNTTAB)        /* HP-UX.  */
  54. #define MOUNTED MNT_MNTTAB
  55. #endif
  56. #if defined(MNTTABNAME)        /* Dynix.  */
  57. #define MOUNTED MNTTABNAME
  58. #endif
  59. #endif
  60. #endif
  61.  
  62. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  63. #include <sys/mount.h>
  64. #endif
  65.  
  66. #ifdef MOUNTED_GETMNT        /* Ultrix.  */
  67. #include <sys/mount.h>
  68. #include <sys/fs_types.h>
  69. #endif
  70.  
  71. #ifdef MOUNTED_FREAD        /* SVR2.  */
  72. #include <mnttab.h>
  73. #endif
  74.  
  75. #ifdef MOUNTED_FREAD_FSTYP    /* SVR3.  */
  76. #include <mnttab.h>
  77. #include <sys/fstyp.h>
  78. #include <sys/statfs.h>
  79. #endif
  80.  
  81. #ifdef MOUNTED_GETMNTENT2    /* SVR4.  */
  82. #include <sys/mnttab.h>
  83. #endif
  84.  
  85. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  86. #include <fshelp.h>
  87. #include <sys/vfs.h>
  88. #endif
  89.  
  90. #ifdef DOLPHIN
  91. /* So special that it's not worth putting this in autoconf.  */
  92. #undef MOUNTED_FREAD_FSTYP
  93. #define MOUNTED_GETMNTTBL
  94. #endif
  95.  
  96. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  97. /* Return the value of the hexadecimal number represented by CP.
  98.    No prefix (like '0x') or suffix (like 'h') is expected to be
  99.    part of CP. */
  100.  
  101. static int xatoi (char *cp)
  102. {
  103.     int val;
  104.  
  105.     val = 0;
  106.     while (*cp) {
  107.     if (*cp >= 'a' && *cp <= 'f')
  108.         val = val * 16 + *cp - 'a' + 10;
  109.     else if (*cp >= 'A' && *cp <= 'F')
  110.         val = val * 16 + *cp - 'A' + 10;
  111.     else if (*cp >= '0' && *cp <= '9')
  112.         val = val * 16 + *cp - '0';
  113.     else
  114.         break;
  115.     cp++;
  116.     }
  117.     return val;
  118. }
  119. #endif                /* MOUNTED_GETMNTENT1.  */
  120.  
  121. #if defined (MOUNTED_GETMNTINFO) && !defined (__NetBSD__)
  122. static char *fstype_to_string (short t)
  123. {
  124.     switch (t) {
  125.     case MOUNT_UFS:
  126.     return "ufs";
  127.     case MOUNT_NFS:
  128.     return "nfs";
  129. #ifdef MOUNT_PC
  130.     case MOUNT_PC:
  131.     return "pc";
  132. #endif
  133. #ifdef MOUNT_MFS
  134.     case MOUNT_MFS:
  135.     return "mfs";
  136. #endif
  137. #ifdef MOUNT_LO
  138.     case MOUNT_LO:
  139.     return "lo";
  140. #endif
  141. #ifdef MOUNT_TFS
  142.     case MOUNT_TFS:
  143.     return "tfs";
  144. #endif
  145. #ifdef MOUNT_TMP
  146.     case MOUNT_TMP:
  147.     return "tmp";
  148. #endif
  149.     default:
  150.     return "?";
  151.     }
  152. }
  153. #endif                /* MOUNTED_GETMNTINFO */
  154.  
  155. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  156. static char *fstype_to_string (int t)
  157. {
  158.     struct vfs_ent *e;
  159.  
  160.     e = getvfsbytype (t);
  161.     if (!e || !e->vfsent_name)
  162.     return "none";
  163.     else
  164.     return e->vfsent_name;
  165. }
  166. #endif                /* MOUNTED_VMOUNT */
  167.  
  168. /* Return a list of the currently mounted filesystems, or NULL on error.
  169.    Add each entry to the tail of the list so that they stay in order.
  170.    If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
  171.    the returned list are valid.  Otherwise, they might not be.
  172.    If ALL_FS is zero, do not return entries for filesystems that
  173.    are automounter (dummy) entries.  */
  174.  
  175. struct mount_entry *read_filesystem_list (int need_fs_type, int all_fs)
  176. {
  177.     struct mount_entry *mount_list;
  178.     struct mount_entry *me;
  179.     struct mount_entry *mtail;
  180.  
  181.     /* Start the list off with a dummy entry. */
  182.     me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
  183.     me->me_next = NULL;
  184.     mount_list = mtail = me;
  185.  
  186. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  187.     {
  188.     struct mntent *mnt;
  189.     char *table = MOUNTED;
  190.     FILE *fp;
  191.     char *devopt;
  192.  
  193.     fp = setmntent (table, "r");
  194.     if (fp == NULL)
  195.         return NULL;
  196.  
  197.     while ((mnt = getmntent (fp))) {
  198.         if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
  199.                 || !strcmp (mnt->mnt_type, "auto")))
  200.         continue;
  201.  
  202.         me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
  203.         me->me_devname = strdup (mnt->mnt_fsname);
  204.         me->me_mountdir = strdup (mnt->mnt_dir);
  205.         me->me_type = strdup (mnt->mnt_type);
  206.         devopt = strstr (mnt->mnt_opts, "dev=");
  207.         if (devopt) {
  208.         if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  209.             me->me_dev = xatoi (devopt + 6);
  210.         else
  211.             me->me_dev = xatoi (devopt + 4);
  212.         } else
  213.         me->me_dev = -1;    /* Magic; means not known yet. */
  214.         me->me_next = NULL;
  215.  
  216.         /* Add to the linked list. */
  217.         mtail->me_next = me;
  218.         mtail = me;
  219.     }
  220.  
  221.     if (endmntent (fp) == 0)
  222.         return NULL;
  223.     }
  224. #endif                /* MOUNTED_GETMNTENT1. */
  225.  
  226. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  227.     {
  228.     struct statfs *fsp;
  229.     int entries;
  230.  
  231.     entries = getmntinfo (&fsp, MNT_NOWAIT);
  232.     if (entries < 0)
  233.         return NULL;
  234.     while (entries-- > 0) {
  235.         me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
  236.         me->me_devname = strdup (fsp->f_mntfromname);
  237.         me->me_mountdir = strdup (fsp->f_mntonname);
  238. #ifdef __NetBSD__
  239.         me->me_type = strdup (fsp->f_fstypename);
  240. #else
  241.         me->me_type = fstype_to_string (fsp->f_type);
  242. #endif
  243.         me->me_dev = -1;    /* Magic; means not known yet. */
  244.         me->me_next = NULL;
  245.  
  246.         /* Add to the linked list. */
  247.         mtail->me_next = me;
  248.         mtail = me;
  249.         fsp++;
  250.     }
  251.     }
  252. #endif                /* MOUNTED_GETMNTINFO */
  253.  
  254. #ifdef MOUNTED_GETMNT        /* Ultrix.  */
  255.     {
  256.     int offset = 0;
  257.     int val;
  258.     struct fs_data fsd;
  259.  
  260.     while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
  261.                   (char *) 0)) > 0) {
  262.         me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
  263.         me->me_devname = strdup (fsd.fd_req.devname);
  264.         me->me_mountdir = strdup (fsd.fd_req.path);
  265.         me->me_type = gt_names[fsd.fd_req.fstype];
  266.         me->me_dev = fsd.fd_req.dev;
  267.         me->me_next = NULL;
  268.  
  269.         /* Add to the linked list. */
  270.         mtail->me_next = me;
  271.         mtail = me;
  272.     }
  273.     if (val < 0)
  274.         return NULL;
  275.     }
  276. #endif                /* MOUNTED_GETMNT. */
  277.  
  278. #if defined (MOUNTED_GETFSSTAT)    /* __alpha running OSF_1 */
  279.     {
  280.     int numsys, counter, bufsize;
  281.     struct statfs *stats;
  282.  
  283.     numsys = getfsstat ((struct statfs *) 0, 0L, MNT_WAIT);
  284.     if (numsys < 0)
  285.         return (NULL);
  286.  
  287.     bufsize = (1 + numsys) * sizeof (struct statfs);
  288.     stats = (struct statfs *) malloc (bufsize);
  289.     numsys = getfsstat (stats, bufsize, MNT_WAIT);
  290.  
  291.     if (numsys < 0) {
  292.         free (stats);
  293.         return (NULL);
  294.     }
  295.     for (counter = 0; counter < numsys; counter++) {
  296.         me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
  297.         me->me_devname = strdup (stats[counter].f_mntfromname);
  298.         me->me_mountdir = strdup (stats[counter].f_mntonname);
  299.         me->me_type = mnt_names[stats[counter].f_type];
  300.         me->me_dev = -1;    /* Magic; means not known yet. */
  301.         me->me_next = NULL;
  302.  
  303.         /* Add to the linked list. */
  304.         mtail->me_next = me;
  305.         mtail = me;
  306.     }
  307.  
  308.     free (stats);
  309.     }
  310. #endif                /* MOUNTED_GETFSSTAT */
  311.  
  312. #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP)    /* SVR[23].  */
  313.     {
  314.     struct mnttab mnt;
  315.     char *table = "/etc/mnttab";
  316.     FILE *fp;
  317.  
  318.     fp = fopen (table, "r");
  319.     if (fp == NULL)
  320.         return NULL;
  321.  
  322.     while (fread (&mnt, sizeof mnt, 1, fp) > 0) {
  323.         me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
  324. #ifdef GETFSTYP            /* SVR3.  */
  325.         me->me_devname = strdup (mnt.mt_dev);
  326. #else
  327.         me->me_devname = malloc (strlen (mnt.mt_dev) + 6);
  328.         strcpy (me->me_devname, "/dev/");
  329.         strcpy (me->me_devname + 5, mnt.mt_dev);
  330. #endif
  331.         me->me_mountdir = strdup (mnt.mt_filsys);
  332.         me->me_dev = -1;    /* Magic; means not known yet. */
  333.         me->me_type = "";
  334. #ifdef GETFSTYP            /* SVR3.  */
  335.         if (need_fs_type) {
  336.         struct statfs fsd;
  337.         char typebuf[FSTYPSZ];
  338.  
  339.         if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
  340.             && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
  341.             me->me_type = strdup (typebuf);
  342.         }
  343. #endif
  344.         me->me_next = NULL;
  345.  
  346.         /* Add to the linked list. */
  347.         mtail->me_next = me;
  348.         mtail = me;
  349.     }
  350.  
  351.     if (fclose (fp) == EOF)
  352.         return NULL;
  353.     }
  354. #endif                /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP.  */
  355.  
  356. #ifdef MOUNTED_GETMNTTBL    /* DolphinOS goes it's own way */
  357.     {
  358.     struct mntent **mnttbl = getmnttbl (), **ent;
  359.     for (ent = mnttbl; *ent; ent++) {
  360.         me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
  361.         me->me_devname = strdup ((*ent)->mt_resource);
  362.         me->me_mountdir = strdup ((*ent)->mt_directory);
  363.         me->me_type = strdup ((*ent)->mt_fstype);
  364.         me->me_dev = -1;    /* Magic; means not known yet. */
  365.         me->me_next = NULL;
  366.  
  367.         /* Add to the linked list. */
  368.         mtail->me_next = me;
  369.         mtail = me;
  370.     }
  371.     endmnttbl ();
  372.     }
  373. #endif
  374.  
  375. #ifdef MOUNTED_GETMNTENT2    /* SVR4.  */
  376.     {
  377.     struct mnttab mnt;
  378.     char *table = MNTTAB;
  379.     FILE *fp;
  380.     int ret;
  381.  
  382.     fp = fopen (table, "r");
  383.     if (fp == NULL)
  384.         return NULL;
  385.  
  386.     while ((ret = getmntent (fp, &mnt)) == 0) {
  387.         me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
  388.         me->me_devname = strdup (mnt.mnt_special);
  389.         me->me_mountdir = strdup (mnt.mnt_mountp);
  390.         me->me_type = strdup (mnt.mnt_fstype);
  391.         me->me_dev = -1;    /* Magic; means not known yet. */
  392.         me->me_next = NULL;
  393.  
  394.         /* Add to the linked list. */
  395.         mtail->me_next = me;
  396.         mtail = me;
  397.     }
  398.  
  399.     if (ret > 0)
  400.         return NULL;
  401.     if (fclose (fp) == EOF)
  402.         return NULL;
  403.     }
  404. #endif                /* MOUNTED_GETMNTENT2.  */
  405.  
  406. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  407.     {
  408.     int bufsize;
  409.     char *entries, *thisent;
  410.     struct vmount *vmp;
  411.  
  412.     /* Ask how many bytes to allocate for the mounted filesystem info.  */
  413.     mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
  414.     entries = malloc (bufsize);
  415.  
  416.     /* Get the list of mounted filesystems.  */
  417.     mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
  418.  
  419.     for (thisent = entries; thisent < entries + bufsize;
  420.          thisent += vmp->vmt_length) {
  421.         vmp = (struct vmount *) thisent;
  422.         me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
  423.         if (vmp->vmt_flags & MNT_REMOTE) {
  424.         char *host, *path;
  425.  
  426.         /* Prepend the remote pathname.  */
  427.         host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
  428.         path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
  429.         me->me_devname = malloc (strlen (host) + strlen (path) + 2);
  430.         strcpy (me->me_devname, host);
  431.         strcat (me->me_devname, ":");
  432.         strcat (me->me_devname, path);
  433.         } else {
  434.         me->me_devname = strdup (thisent +
  435.                       vmp->vmt_data[VMT_OBJECT].vmt_off);
  436.         }
  437.         me->me_mountdir = strdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
  438.         me->me_type = strdup (fstype_to_string (vmp->vmt_gfstype));
  439.         me->me_dev = -1;    /* vmt_fsid might be the info we want.  */
  440.         me->me_next = NULL;
  441.  
  442.         /* Add to the linked list. */
  443.         mtail->me_next = me;
  444.         mtail = me;
  445.     }
  446.     free (entries);
  447.     }
  448. #endif                /* MOUNTED_VMOUNT. */
  449.  
  450.     /* Free the dummy head. */
  451.     me = mount_list;
  452.     mount_list = mount_list->me_next;
  453.     free (me);
  454.     return mount_list;
  455. }
  456. #endif /* NO_INFOMOUNT */
  457.